from iClouds.apiSerializers import *
from iClouds.apiExceptions import *
from iClouds.apiheader import *
from django_celery_beat.models import (
    IntervalSchedule,
    CrontabSchedule,
    ClockedSchedule,
    PeriodicTask,
    PeriodicTasks,
)
import json, time


# AI属性
class AllinpayRobotConfigSerializer(serializers.ModelSerializer):
    card = SerializerMethodField()  # 是否会员
    shard = SerializerMethodField()
    sales = SerializerMethodField()  # 租用，评分

    class Meta:
        model = AllinpayRobotConfig
        fields = "__all__"
        # exclude = ["status"]

    def get_card(self, attr):
        """ai会员"""
        r = AllinpayRobotListvip.objects.filter(mid=attr.id)
        if not r.count():
            return None
        else:
            return r.last().outtime

    def get_shard(self, attr):
        """ai分享"""
        try:
            r = AllinpayRobotConfigShare.objects.get(id=attr.id)
        except BaseException as err:
            return None
        else:
            return ModelAllinpayRobotConfigShareSerializer(r).data

    def get_sales(self, attr):
        """租用次数，评分"""
        r = AllinpayRobotConfigSales.objects.filter(
            mid=attr.id, score__isnull=False
        ).aggregate(
            count=Count("id"), max=Max("score"), min=Min("score"), avg=Avg("score")
        )
        return r


class AllinpayRobotConfigPostSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    name = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        help_text="姓名",
    )
    description = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="简介",
    )
    image = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="证照url,绝对路径",
    )
    language = ChoiceField(
        choices=(
            "Chinese",
            "English",
            "Japanese",
            "中英混合",
            "日英混合",
            "多语种混合",
        ),
        default="Chinese",
        help_text="语言",
    )
    gender = IntegerField(
        allow_null=True, max_value=1, min_value=0, required=False, help_text="性别"
    )
    status = IntegerField(read_only=True, help_text="状态")
    answer = IntegerField(read_only=True, help_text="创作者")
    audio = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        help_text="原始训练语音url,绝对路径",
    )
    content = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        style={"base_template": "textarea.html"},
        help_text="原始训练文本url,绝对路径",
    )

    card = SerializerMethodField()  # 是否会员
    shard = SerializerMethodField()  # 分享
    sales = SerializerMethodField()  # 租用，评分

    class Meta:
        model = AllinpayRobotConfig
        fields = [
            "id",
            "name",
            "description",
            "image",
            "language",
            "gender",
            "status",
            "answer",
            "audio",
            "content",
            "card",
            "shard",
            "sales",
        ]

    def get_card(self, attr):
        """ai会员"""
        r = AllinpayRobotListvip.objects.filter(mid=attr.id)
        if not r.count():
            return None
        else:
            return r.last().outtime

    def get_shard(self, attr):
        """ai分享"""
        print("hello")
        try:
            r = AllinpayRobotConfigShare.objects.get(id=attr.id)
        except BaseException as err:
            print(err)
            return None
        else:
            print(r.id)
            return ModelAllinpayRobotConfigShareSerializer(r).data

    def get_sales(self, attr):
        """租用次数，评分"""
        r = AllinpayRobotConfigSales.objects.filter(
            mid=attr.id, score__isnull=False
        ).aggregate(
            count=Count("id"), max=Max("score"), min=Min("score"), avg=Avg("score")
        )
        return r


# print(repr(AllinpayRobotConfigPostSerializer()))


# 个人信息
class AllinpayRobotListSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    nicename = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="昵称",
    )
    basename = CharField(
        allow_blank=True, allow_null=True, max_length=255, help_text="姓名"
    )
    gender = IntegerField(
        allow_null=True, max_value=1, min_value=0, required=False, help_text="性别"
    )
    birthday = DateField(allow_null=True, required=False, help_text="生日")
    phone = CharField(
        allow_blank=True, allow_null=True, required=False, help_text="电话"
    )
    email = CharField(
        allow_blank=True, allow_null=True, required=False, help_text="邮箱"
    )
    height = IntegerField(allow_null=True, required=False, help_text="身高(mm)")
    weight = IntegerField(allow_null=True, required=False, help_text="体重(g)")

    isbot = IntegerField(min_value=0, default=1, help_text="AI角色ID")
    status = IntegerField(read_only=True, help_text="状态")
    create = DateTimeField(read_only=True, help_text="创建时间")
    lasttime = DateTimeField(read_only=True, help_text="活跃时间")
    parent = IntegerField(read_only=True, help_text="身份识别")

    face = CharField(default="/static/models/models/0000.png", help_text="头像")
    share = IntegerField(min_value=0, default=0, help_text="是否共享")
    linkforme = CharField(
        allow_blank=True, allow_null=True, required=False, help_text="关系"
    )
    auth = CharField(
        allow_blank=True, allow_null=True, required=False, help_text="权鉴答案"
    )
    photo = CharField(
        allow_blank=True,
        allow_null=True,
        default="https://oss.3vppt.com/ppt_media/FlNerDya115fUjTeVlTmaGZI-3GZ&tmp_14d773614a20801336fb5dd880f9c574.png",
        help_text="默认形象照片",
    )
    tags = SerializerMethodField()
    attr = SerializerMethodField()
    # card = SerializerMethodField()
    # shre = SerializerMethodField()

    class Meta:
        model = AllinpayRobotList
        fields = "__all__"

    def get_tags(self, attr):
        """tag列表"""
        r = AllinpayRobotTag.objects.filter(parent=attr.id)
        return ModelAllinpayRobotTagSerializer(r, many=True).data

    def get_attr(self, attr):
        """ai属性"""
        try:
            r = AllinpayRobotConfig.objects.get(id=attr.isbot)
        except BaseException as err:
            return None
        else:
            return ModelAllinpayRobotConfigSerializer(r).data

    def get_card(self, attr):
        """ai会员"""
        r = AllinpayRobotListvip.objects.filter(mid=attr.isbot)
        if not r.count():
            return None
        else:
            return r.last().outtime


class AllinpayRobotTagSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    parent = IntegerField(allow_null=True, help_text="AI好友ID")
    lte = IntegerField(allow_null=True, help_text="标签类型")
    tag = CharField(
        allow_blank=True, allow_null=True, max_length=255, help_text="标签内容"
    )

    class Meta:
        model = AllinpayRobotTag
        fields = "__all__"


# 朋友圈部分
class AllinpayRobotFriendsSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    title = CharField(
        allow_blank=True, allow_null=True, required=False, help_text="标题"
    )
    types = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="类型",
    )
    html = CharField(
        allow_blank=True,
        allow_null=True,
        style={"base_template": "textarea.html"},
        help_text="正文",
    )
    create = DateTimeField(read_only=True, help_text="创建时间")
    answer = IntegerField(min_value=1, help_text="虚拟身份ID")
    status = IntegerField(read_only=True, help_text="状态")
    lasttime = DateTimeField(read_only=True, help_text="活跃时间")

    pin = SerializerMethodField()
    zan = SerializerMethodField()
    sou = SerializerMethodField()
    zoe = SerializerMethodField()

    class Meta:
        model = AllinpayRobotFriends
        fields = "__all__"

    def get_pin(self, attr):
        r = AllinpayRobotRemark.objects.filter(idx=attr.id)
        return r.count()

    def get_zan(self, attr):
        r = AllinpayRobotGoods.objects.filter(idx=attr.id)
        return r.count()

    def get_sou(self, attr):
        r = AllinpayRobotCollect.objects.filter(idx=attr.id)
        return r.count()

    def get_zoe(self, attr):
        r = AllinpayRobotRepeat.objects.filter(idx=attr.id)
        return r.count()


class AllinpayRobotRemarkSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    idx = IntegerField(min_value=1, help_text="文章ID")
    tag = CharField(
        allow_blank=True,
        allow_null=True,
        style={"base_template": "textarea.html"},
        help_text="评论内容",
    )
    answer = IntegerField(min_value=1, help_text="虚拟身份ID")
    create = DateTimeField(read_only=True)

    class Meta:
        model = AllinpayRobotRemark
        fields = "__all__"


class AllinpayRobotGoodsSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    idx = IntegerField(min_value=1, help_text="文章ID")
    tap = IntegerField(
        allow_null=True, max_value=1, min_value=-1, help_text="赞1 or 踩-1"
    )
    answer = IntegerField(min_value=1, help_text="虚拟身份ID")
    create = DateTimeField(read_only=True)

    class Meta:
        model = AllinpayRobotGoods
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=AllinpayRobotGoods.objects.all(), fields=("idx", "answer")
            )
        ]


class AllinpayRobotCollectSerializer(serializers.ModelSerializer):
    """收藏"""

    id = IntegerField(label="ID", read_only=True)
    idx = IntegerField(min_value=1, help_text="文章ID")
    tap = IntegerField(read_only=True)
    answer = IntegerField(min_value=1, help_text="虚拟身份ID")
    create = DateTimeField(read_only=True)

    class Meta:
        model = AllinpayRobotCollect
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=AllinpayRobotCollect.objects.all(), fields=("idx", "answer")
            )
        ]


class AllinpayRobotRepeatSerializer(serializers.ModelSerializer):
    """转发"""

    id = IntegerField(label="ID", read_only=True)
    idx = IntegerField(min_value=1, help_text="文章ID")
    tap = IntegerField(read_only=True)
    answer = IntegerField(min_value=1, help_text="虚拟身份ID")
    create = DateTimeField(read_only=True)

    class Meta:
        model = AllinpayRobotRepeat
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=AllinpayRobotRepeat.objects.all(), fields=("idx", "answer")
            )
        ]


class AllinpayRobotBaseSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    name = CharField(allow_blank=True, allow_null=True, help_text="名称")
    face = CharField(allow_blank=True, allow_null=True, help_text="寸照")
    sound = CharField(allow_blank=True, allow_null=True, help_text="音频")
    answer = IntegerField(min_value=1, help_text="虚拟身份ID")
    status = IntegerField(read_only=True)
    create = DateTimeField(read_only=True)
    lasttime = DateTimeField(read_only=True)

    class Meta:
        model = AllinpayRobotBase
        fields = "__all__"


# ========================================================================================
# 文本聊闲
# ========================================================================================
class UploadLocalSerializer(serializers.Serializer):
    """语音解析"""

    user = IntegerField(help_text="虚拟AI身份ID")
    audio = serializers.FileField(allow_empty_file=False)

    class Meta:
        fields = "__all__"


class AudioToTextSerializer(serializers.Serializer):
    user = IntegerField(help_text="虚拟AI身份ID")
    audio = CharField(allow_blank=True, allow_null=True, help_text="音频url")
    # etag = CharField(allow_blank=True, allow_null=True, help_text="七牛云存储标识")

    class Meta:
        fields = "__all__"


class RebotChatTextSerializer(serializers.Serializer):
    """文本合成任务"""

    user = IntegerField(help_text="虚拟AI身份ID")
    share = IntegerField(default=0, help_text="是否共享好友 (0|1)")
    # cast = ChoiceField(choices=("Text", "Sound"), help_text="聊天类型(Text,Sound)")
    chat = CharField(allow_blank=True, allow_null=True, help_text="提问")
    # chat = ListField(
    #     child=JSONField(), max_length=6, min_length=1, help_text="聊天上下文列表"
    # )

    class Meta:
        fields = "__all__"


class RebotAudioPostSerializer(serializers.Serializer):
    """AI音频合成任务"""

    user = IntegerField(help_text="虚拟好友ID")
    chat = CharField(
        allow_blank=True, allow_null=True, min_length=10, help_text="合成文本"
    )

    class Meta:
        fields = "__all__"


class RebotVideoPostSerializer(serializers.Serializer):
    """AI视频合成任务"""

    # video
    user = IntegerField(help_text="虚拟好友ID")
    audio = CharField(allow_blank=True, allow_null=True, help_text="音频url(>2s)")
    image = CharField(allow_blank=True, allow_null=True, help_text="寸照url")
    lange = IntegerField(max_value=10, min_value=2, default=2, help_text="时长(秒)")

    class Meta:
        fields = "__all__"


class RebotChatPostSerializer(serializers.Serializer):
    """合成任务提交"""

    guid = CharField(allow_blank=True, allow_null=True, help_text="guid")
    mode = CharField(allow_blank=True, allow_null=True, help_text="guid")
    code = IntegerField(help_text="错误代码")
    data = CharField(allow_blank=True, allow_null=True, help_text="资源地址")
    plan = CharField(allow_blank=True, allow_null=True, default="1/1", help_text="进度")

    class Meta:
        fields = "__all__"


class RebotChatGetSerializer(serializers.Serializer):
    guid = CharField(allow_blank=True, allow_null=True, help_text="guid")

    class Meta:
        fields = "__all__"


# ========================================================================================
# 订阅事件
# ========================================================================================


class AllinpayRobotModelsSerializer(serializers.ModelSerializer):
    """事件模板"""

    id = IntegerField(label="ID", read_only=True)
    name = CharField(
        allow_blank=True, allow_null=True, max_length=255, help_text="模板名称"
    )
    mode = ChoiceField(
        choices=("content", "Voice", "Lipsync"),
        help_text="媒体类型(content 文本订阅, Voice 音频订阅, lipsync 视频订阅)",
    )
    content = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        style={"base_template": "textarea.html"},
        help_text="模板内容",
    )
    mark = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="自定义消息",
    )
    # image = CharField(
    #     allow_blank=True,
    #     allow_null=True,
    #     required=False,
    #     help_text="图片",
    # )
    # audio = CharField(
    #     allow_blank=True,
    #     allow_null=True,
    #     required=False,
    #     help_text="音频",
    # )
    # video = CharField(
    #     allow_blank=True,
    #     allow_null=True,
    #     required=False,
    #     help_text="视频",
    # )
    answer = IntegerField(help_text="创建者")
    status = IntegerField(read_only=True, help_text="状态")
    create = DateTimeField(read_only=True, help_text="创建时间")

    shard = SerializerMethodField()
    sales = SerializerMethodField()  # 租用，评分

    class Meta:
        model = AllinpayRobotModels
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=AllinpayRobotModels.objects.all(), fields=("name", "answer")
            )
        ]

    def get_shard(self, attr):
        """ai分享"""
        try:
            r = AllinpayRobotModelsShare.objects.get(id=attr.id)
        except BaseException as err:
            return 0
        else:
            return r.status

    def get_sales(self, attr):
        """租用次数，评分"""
        r = AllinpayRobotModelsSales.objects.filter(
            mid=attr.id, score__isnull=False
        ).aggregate(
            count=Count("id"), max=Max("score"), min=Min("score"), avg=Avg("score")
        )
        return r

    # def validate(self, attrs):
    #     if attrs["mode"] == "Mpeg":
    #         if not attrs.get("video"):
    #             raise ValidationError("必须提供视频url")
    #     return attrs


class PeriodicTaskSerializer(serializers.Serializer):
    timer = ChoiceField(
        choices=("固定时间", "CRON时间", "固定间隔"),
        help_text="定时器类型",
    )
    schd = IntegerField(help_text="定时器ID")
    mode = IntegerField(help_text="订阅模板ID")
    user = IntegerField(help_text="虚拟用户ID")
    share = IntegerField(default=0, help_text="是否公共好友 0|1")
    video = CharField(
        allow_blank=True,
        allow_null=True,
        required=False,
        help_text="视频",
    )

    class Meta:
        fields = "__all__"

    def create(self, validated_data):
        # print(validated_data)
        kwargs = {}
        if validated_data["timer"] == "固定时间":
            kwargs["clocked"] = self.has_clock(validated_data["schd"])
        elif validated_data["timer"] == "CRON时间":
            kwargs["crontab"] = self.has_cront(validated_data["schd"])
        elif validated_data["timer"] == "固定间隔":
            kwargs["interval"] = self.has_inter(validated_data["schd"])
        else:
            raise ValidationError("字段错误的值")
        kwargs["name"] = (
            f'Subscribe events for {validated_data["mode"]} By {validated_data["user"]} To {validated_data["answer"]}'
        )
        kwargs["task"] = "rebot.tasks.AI_Auto_Tasks_Event"
        kwargs["kwargs"] = json.dumps(
            {
                "event": validated_data["mode"],
                "usert": validated_data["user"],
                "answer": validated_data["answer"],
                "share": validated_data["share"],
                "video": validated_data.get("video"),
            }
        )
        kwargs["enabled"] = True
        name = kwargs.pop("name")
        # return PeriodicTask.objects.create(**kwargs)
        return PeriodicTask.objects.update_or_create(defaults=kwargs, name=name)[0]

    def has_inter(self, val):
        try:
            r = IntervalSchedule.objects.get(id=val)
        except BaseException as err:
            raise ValidationError("固定间隔 对象不存在")
        else:
            return r

    def has_cront(self, val):
        try:
            r = CrontabSchedule.objects.get(id=val)
        except BaseException as err:
            raise ValidationError("CRON时间 对象不存在")
        else:
            return r

    def has_clock(self, val):
        try:
            r = ClockedSchedule.objects.get(id=val)
        except BaseException as err:
            raise ValidationError("固定时间 对象不存在")
        else:
            return r


class AllinpayRobotQiniuSerializer(serializers.ModelSerializer):
    """历史多媒体任务"""

    id = IntegerField(label="ID", read_only=True)
    uid = IntegerField(allow_null=True, required=False)
    guid = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
    types = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
    url = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
    create = DateTimeField(allow_null=True, required=False)

    class Meta:
        model = AllinpayRobotQiniu
        fields = "__all__"


# ========================================================
# 支付部分
# ========================================================


class AllinpayRobotMoneyTaocanSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    name = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="套餐名称",
    )
    money = IntegerField(allow_null=True, required=False, help_text="代币ID")
    fund = IntegerField(allow_null=True, required=False, help_text="代币数量")
    amount = IntegerField(allow_null=True, required=False, help_text="法币金额(分)")
    status = IntegerField(allow_null=True, required=False, help_text="套餐状态")
    lasttime = DateTimeField(allow_null=True, required=False, help_text="有效期")
    description = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="套餐简介",
    )

    moneye = SerializerMethodField()

    class Meta:
        model = AllinpayRobotMoneyTaocan
        fields = "__all__"

    def get_moneye(self, attr):
        try:
            r = AllinpayRobotMoney.objects.get(id=attr.money)
        except BaseException as err:
            return None
        else:
            return ModelAllinpayRobotMoneySerializer(r).data


class AllinpayRobotReqsnSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    appid = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
    mchid = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
    reqsn = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        validators=[UniqueValidator(queryset=AllinpayRobotReqsn.objects.all())],
    )
    description = CharField(
        allow_blank=True, allow_null=True, max_length=255, required=False
    )
    openid = CharField(
        allow_blank=True, allow_null=True, max_length=255, required=False
    )
    amount = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    answer = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    mark = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    fund = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    preson = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    money = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    total = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    status = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    creattime = DateTimeField(allow_null=True, required=False)
    lasttime = DateTimeField(allow_null=True, required=False)
    transaction_id = CharField(
        allow_blank=True, allow_null=True, max_length=255, required=False
    )

    class Meta:
        model = AllinpayRobotReqsn
        fields = "__all__"


class AllinpayRobotReqsnPostSerializer(serializers.Serializer):
    """创建支付订单"""

    id = IntegerField(label="ID", read_only=True)
    appid = CharField(read_only=True)
    mchid = CharField(read_only=True)
    reqsn = CharField(read_only=True)
    description = CharField(read_only=True)
    openid = CharField(read_only=True)
    amount = IntegerField(read_only=True)
    answer = IntegerField(read_only=True)
    mark = IntegerField(read_only=True)
    money = IntegerField(read_only=True)
    total = IntegerField(read_only=True)
    status = IntegerField(read_only=True)
    creattime = DateTimeField(read_only=True)
    preson = IntegerField(allow_null=True, help_text="套餐ID")
    fund = IntegerField(allow_null=True, min_value=1, help_text="购买数量")

    class Meta:
        fields = "__all__"

    def create(self, validated_data):
        kwargs = {}
        uid = validated_data.get("answer")
        pid = validated_data.get("preson")
        cte = validated_data.get("creattime")
        num = validated_data.get("fund")
        try:
            u = AllinpayWxchatList.objects.get(userid=uid)
            b = AllinpayRobotMoney.objects.get(id=settings.ROBOT_MONEY_DEFAULT)
            p = AllinpayRobotMoneyTaocan.objects.get(id=pid, status=1, lasttime__gt=cte)
        except AllinpayWxchatList.DoesNotExist as err:
            raise ValidationError("缺少用户信息")
        except AllinpayRobotMoney.DoesNotExist as err:
            raise ValidationError("缺少代币信息")
        except AllinpayRobotMoneyTaocan.DoesNotExist as err:
            raise ValidationError("缺少套餐信息")
        except BaseException as err:
            raise ValidationError("缺少信息")
        kwargs["reqsn"] = (
            f'AI{time.strftime("%Y%m%d%H%M%S", time.localtime())}{has_chocode(6)}'
        )
        kwargs["description"] = f"{b.nicename}充值"
        kwargs["creattime"] = cte
        kwargs["answer"] = uid
        kwargs["preson"] = pid  # 套餐ID
        kwargs["fund"] = num  # 套餐数量
        kwargs["money"] = p.fund * num  # 代币数量
        kwargs["amount"] = p.amount * num  # 法币金额
        kwargs["mark"] = 1
        kwargs["openid"] = u.appid  # 用户openid
        return AllinpayRobotReqsn.objects.create(**kwargs)


class AllinpayRobotReqsnCloseSerializer(serializers.Serializer):
    """关闭支付订单"""

    out_trade_no = CharField(
        allow_blank=True, allow_null=True, max_length=255, help_text="商户订单号"
    )

    def validate_out_trade_no(self, attr):
        try:
            r = AllinpayRobotReqsn.objects.get(reqsn=attr)
        except BaseException as err:
            raise ValidationError("记录不存在")
        else:
            if r.status:
                raise ValidationError("该记录已经完成")
        return attr

    class Meta:
        fields = "__all__"


class AllinpayRobotReqsnRefundSerializer(serializers.Serializer):
    """退单字符订单"""

    out_trade_no = CharField(
        allow_blank=True, allow_null=True, max_length=255, help_text="原商户订单号"
    )
    amount = IntegerField(
        allow_null=True, min_value=1, help_text="退款金额(原订单实际支付金额)"
    )

    def validate(self, attrs):
        try:
            r = AllinpayRobotReqsn.objects.get(reqsn=attrs["out_trade_no"])
        except BaseException as err:
            raise ValidationError("记录不存在")
        else:
            if not r.status == 1:
                raise ValidationError("该订单不能退款")
            if not r.total == attrs["amount"]:
                raise ValidationError("金额校验失败")
            # if r.lasttime + timedelta(days=3) < timezone.now():
            #     raise ValidationError("订单已经过期")
        return attrs

    class Meta:
        fields = "__all__"


class AllinpayUserVerifySerializer(serializers.Serializer):
    cypher = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="旧密码",
    )
    password = CharField(
        allow_blank=True, allow_null=True, max_length=255, help_text="新密码"
    )

    class Meta:
        fields = "__all__"

    def create(self, validated_data):
        cypher = validated_data.get("cypher")
        password = validated_data.get("password")
        lasttime = validated_data.get("lasttime")
        answer = validated_data.get("answer")

        try:
            r = AllinpayUserVerify.objects.get(id=answer)
        except BaseException as err:
            pass
        else:
            if not r.password == cypher:
                raise ValidationError("旧密码校验失败")
        return AllinpayUserVerify.objects.update_or_create(
            defaults={"password": password, "lasttime": lasttime}, id=answer
        )[0]


class AllinpayRobotReqsndofundSerializer(serializers.Serializer):
    orderno = CharField(
        allow_blank=True, allow_null=True, max_length=255, help_text="原始订单号"
    )
    reqsn = CharField(read_only=True)
    orderid = IntegerField(read_only=True)
    answer = IntegerField(read_only=True)
    current = DateTimeField(read_only=True)
    status = IntegerField(read_only=True)
    officer = IntegerField(read_only=True)
    lasttime = DateTimeField(read_only=True)

    class Meta:
        fields = "__all__"

    def create(self, validated_data):
        kwargs = {}
        try:
            r = AllinpayRobotReqsn.objects.get(
                reqsn=validated_data.get("orderno"), status=1, mark=1
            )
        except BaseException as err:
            raise ValidationError("原始订单无效")
        else:
            if r.lasttime + timedelta(days=3) < timezone.now():
                raise ValidationError("订单已经过期")
        # kwargs["reqsn"] = (
        #     f'RF{time.strftime("%Y%m%d%H%M%S", time.localtime())}{has_chocode(6)}'
        # )
        kwargs["orderid"] = r.id
        kwargs["answer"] = validated_data.get("answer")
        kwargs["status"] = 0
        kwargs["current"] = timezone.now()
        return AllinpayRobotReqsnRefund.objects.create(**kwargs)


# =============================================================================================
# class AllinpayRobotListvipSerializer(serializers.ModelSerializer):
#     id = IntegerField(label='ID', read_only=True)
#     mid = IntegerField(allow_null=True, max_value=2147483647, min_value=-2147483648, required=False)
#     month = IntegerField(allow_null=True, min_value=1, required=False)
#     reqsn = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
#     outtime = DateTimeField(allow_null=True, required=False)
#     current = DateTimeField(allow_null=True, required=False)
#     class Meta:
#         model = AllinpayRobotListvip
#         fields = "__all__"
# ============================================================================================
# ai模型
class AllinpayRobotListvipPostSerializer(serializers.Serializer):
    """模型充值"""

    mid = IntegerField(help_text="模型ID")
    month = IntegerField(default=1, min_value=1, max_value=12, help_text="年")
    # pswd = CharField(write_only=True, help_text="特权密码")
    amount = IntegerField(read_only=True)
    reqsn = CharField(read_only=True)
    outtime = DateTimeField(read_only=True)
    current = DateTimeField(read_only=True)

    answer = SerializerMethodField()

    class Meta:
        fields = "__all__"

    def has_outtime(self, mid):
        """获取有效期"""
        r = AllinpayRobotListvip.objects.filter(mid=mid)
        if not r.count():
            return timezone.now()
        else:
            return r.last().outtime

    def get_answer(self, attr):
        """调取用户ID"""
        try:
            r = AllinpayRobotConfig.objects.get(id=attr.mid)
        except BaseException as err:
            return None
        else:
            return r.answer

    def create(self, vdata):
        kwargs = {}
        try:
            r = AllinpayRobotConfig.objects.get(id=vdata.get("mid"))
        #     p = AllinpayUserVerify.objects.get(id=r.answer, password=vdata.get("pswd"))
        # except AllinpayRobotConfig.DoesNotExist as err:
        #     raise ValidationError("AI模型不存在")
        # except AllinpayUserVerify.DoesNotExist as err:
        #     raise ValidationError("特权密码校验失败")
        except BaseException as err:
            raise ValidationError("AI模型不存在")
        kwargs["mid"] = vdata.get("mid")
        kwargs["month"] = 1  # vdata.get("month")
        kwargs["amount"] = settings.ROBOT_MONEY_MYMODEL * 1  # * vdata.get("month")
        kwargs["reqsn"] = (
            f'VP{time.strftime("%Y%m%d%H%M%S", time.localtime())}{has_chocode(6)}'
        )
        kwargs["current"] = timezone.now()
        # kwargs["outtime"] = self.has_outtime(vdata.get("mid")) + timedelta(        # days=vdata.get("month")
        #     days=365
        # )
        kwargs["outtime"] = timezone.now() + timedelta(days=365)
        return AllinpayRobotListvip.objects.create(**kwargs)


class AllinpayRobotConfigShareSerializer(serializers.Serializer):
    mid = IntegerField(help_text="模型ID")
    audio = IntegerField(default=0, min_value=0, help_text="TTS价格 文本合成音频(条)")
    # video = IntegerField(help_text="视频价格 60秒 音频合成视频")
    # movie = IntegerField(help_text="电影价格 50字 文本合成视频")
    # pswd = CharField(write_only=True, help_text="特权密码")

    class Meta:
        fields = "__all__"

    def has_outtime(self, mid):
        """获取有效期"""
        r = AllinpayRobotListvip.objects.filter(mid=mid)
        if not r.count():
            return timezone.now()
        else:
            return r.last().outtime

    def create(self, vdata):
        kwargs = {}
        mid = vdata.get("mid")
        answer = vdata.get("answer")
        try:
            r = AllinpayRobotConfig.objects.get(id=mid)
            # p = AllinpayUserVerify.objects.get(id=r.answer, password=vdata.get("pswd"))
        # except AllinpayRobotConfig.DoesNotExist as err:
        #     raise ValidationError("AI模型不存在")
        # except AllinpayUserVerify.DoesNotExist as err:
        #     raise ValidationError("特权密码校验失败")
        except BaseException as err:
            raise ValidationError("AI模型不存在")
        else:
            if not r.answer == answer:
                raise ValidationError("AI模型不是自己的")
            if not r.status:
                raise ValidationError("AI模型未训练")
            if self.has_outtime(mid) < timezone.now():
                raise ValidationError("AI模型未升级")
        kwargs["id"] = r.id
        kwargs["status"] = 1
        kwargs["answer"] = answer
        kwargs["current"] = timezone.now()
        kwargs["audio"] = vdata.get("audio")
        return AllinpayRobotConfigShare.objects.create(**kwargs)

    def update(self, instance, vdata):
        # instance.status = vdata.get("status", instance.status)
        # instance.answer = vdata.get("answer", instance.answer)
        # instance.current = vdata.get("current", instance.current)
        instance.audio = vdata.get("audio", instance.audio)
        instance.video = vdata.get("video", instance.video)
        instance.movie = vdata.get("movie", instance.movie)
        instance.save()
        return instance


class AllinpayRobotConfigSalesSerializer(serializers.Serializer):
    # reqsn = CharField(allow_null=True, help_text="订单号")
    ssid = IntegerField(help_text="记录ID")
    score = IntegerField(
        allow_null=True, max_value=10, min_value=0, help_text="评分0-10"
    )

    class Meta:
        fields = "__all__"


# ===========================================================================================
# ai模板
class AllinpayRobotModelsShareSerializer(serializers.Serializer):
    """分享模板"""

    mid = IntegerField(help_text="模板ID")
    # pswd = CharField(write_only=True, help_text="特权密码")

    class Meta:
        fields = "__all__"

    def create(self, vdata):
        kwargs = {}
        mid = vdata.get("mid")
        answer = vdata.get("answer")
        try:
            r = AllinpayRobotModels.objects.get(id=mid)
        #     p = AllinpayUserVerify.objects.get(id=r.answer, password=vdata.get("pswd"))
        # except AllinpayRobotModels.DoesNotExist as err:
        #     raise ValidationError("AI模板不存在")
        # except AllinpayUserVerify.DoesNotExist as err:
        #     raise ValidationError("特权密码校验失败")
        except BaseException as err:
            raise ValidationError("AI模板不存在")
        else:
            if not r.answer == answer:
                raise ValidationError("AI模板不是自己的")
            if not r.status:
                raise ValidationError("AI模板未启用")

        try:
            s = AllinpayRobotModelsShare.objects.get(id=r.id)
        except BaseException as err:
            kwargs["id"] = r.id
            kwargs["status"] = 1
            kwargs["answer"] = answer
            kwargs["current"] = timezone.now()
            return AllinpayRobotModelsShare.objects.create(**kwargs)
        else:
            s.status = 1
            s.save()
            return s


class AllinpayRobotModelsSalesSerializer(serializers.Serializer):
    reqsn = CharField(allow_null=True, help_text="订单号")
    score = IntegerField(
        allow_null=True, max_value=10, min_value=0, help_text="评分0-10"
    )

    class Meta:
        fields = "__all__"


# ==========================================================================
# 新核心功能
# ==========================================================================
class NewRebotAudioPostSerializer(serializers.Serializer):
    """AI音频合成任务"""

    user = IntegerField(help_text="AI模型ID")
    # pswd = CharField(help_text="特权密码")
    language = ChoiceField(
        choices=[
            "Chinese",
            "English",
            "Japanese",
            "中英混合",
            "日英混合",
            "多语种混合",
        ],
        help_text='模型语言:["Chinese","English","Japanese","中英混合","日英混合","多语种混合"]',
    )
    chat = CharField(
        allow_blank=True,
        allow_null=True,
        min_length=10,
        # max_length=100,
        help_text="合成文本",
    )
    # 幻觉参数
    # top_k = IntegerField(min_value=0, max_value=100, default=5)
    # top_p = IntegerField(min_value=0, max_value=1, default=1)
    # temperature = IntegerField(min_value=0, max_value=1, default=1)

    class Meta:
        fields = "__all__"

    def validate_user(self, attr):
        """验证模型状态"""
        try:
            r = AllinpayRobotConfig.objects.get(id=attr, status=1)
        except BaseException as err:
            raise ValidationError(f"ai模型错误:{err}")
        else:
            return attr


class AllinpayRobotQiniuLogSerializer(serializers.ModelSerializer):
    id = IntegerField(label="ID", read_only=True)
    reqsn = CharField(max_length=255, required=False)
    guid = CharField(max_length=255, required=False)
    mode = CharField(allow_blank=True, required=False)
    mark = CharField(allow_blank=True, required=False)
    answer = IntegerField(allow_null=True, required=False)
    model = IntegerField(allow_null=True, required=False)
    mate = IntegerField(allow_null=True, required=False)
    matr = IntegerField(allow_null=True, required=False)
    matter = CharField(allow_blank=True, required=False)
    chat = CharField(allow_blank=True, allow_null=True, required=False)
    language = CharField(allow_blank=True, allow_null=True, required=False)
    image = CharField(allow_blank=True, allow_null=True, required=False)
    audio = CharField(allow_blank=True, allow_null=True, required=False)
    video = CharField(allow_blank=True, allow_null=True, required=False)
    amoney = IntegerField(allow_null=True, min_value=0, required=False)
    status = IntegerField(allow_null=True, min_value=0, required=False)
    current = DateTimeField(allow_null=True, required=False)
    lasttime = DateTimeField(allow_null=True, required=False)
    sell = IntegerField(allow_null=True, required=False)
    description = CharField(
        allow_blank=True, allow_null=True, max_length=255, required=False
    )
    resource = CharField(
        allow_blank=True, allow_null=True, max_length=255, required=False
    )

    modelinfo = SerializerMethodField()
    frienders = SerializerMethodField()

    class Meta:
        model = AllinpayRobotQiniuLog
        fields = "__all__"

    def get_modelinfo(self, attr):
        """模型信息"""
        try:
            res = AllinpayRobotConfig.objects.get(id=attr.model)
        except BaseException as err:
            return None
        else:
            return ModelAllinpayRobotConfigSerializer(res).data

    def get_frienders(self, attr):
        """好友信息"""
        try:
            if attr.matr:
                res = AllinpayRobotListmyShare.objects.get(id=attr.mate)
                db = ModelAllinpayRobotListmyShareSerializer(res).data
            else:
                res = AllinpayRobotList.objects.get(id=attr.mate)
                db = ModelAllinpayRobotListSerializer(res).data
        except BaseException as err:
            return None
        else:
            return db

    def create(self, vdata):
        kwargs = {}
        kwargs["reqsn"] = vdata.get("reqsn")
        kwargs["mode"] = vdata.get("mode")
        kwargs["answer"] = vdata.get("answer")
        kwargs["amoney"] = vdata.get("amoney")
        kwargs["status"] = 0
        kwargs["current"] = timezone.now()
        if vdata.get("guid"):
            kwargs["guid"] = vdata.get("guid")
        else:
            kwargs["guid"] = str(uuid.uuid1())
        # print(vdata.get("user"), vdata)
        if vdata.get("model"):
            kwargs["model"] = vdata.get("model")
        if vdata.get("mate"):
            kwargs["mate"] = vdata.get("mate")
        if vdata.get("matter"):
            kwargs["matter"] = vdata.get("matter")
        if vdata.get("chat"):
            kwargs["chat"] = vdata.get("chat")
        if vdata.get("language"):
            kwargs["language"] = vdata.get("language")
        if vdata.get("image"):
            kwargs["image"] = vdata.get("image")
        if vdata.get("audio"):
            kwargs["audio"] = vdata.get("audio")
        if vdata.get("video"):
            kwargs["video"] = vdata.get("video")
        if vdata.get("sell"):
            kwargs["sell"] = vdata.get("sell")
        if vdata.get("matr"):
            kwargs["matr"] = vdata.get("matr")
        # print(kwargs)
        return AllinpayRobotQiniuLog.objects.create(**kwargs)


class NewRebotVideoPostSerializer(serializers.Serializer):
    """AI视频合成任务"""

    # video
    # pswd = CharField(help_text="特权密码")
    audio = CharField(allow_blank=True, allow_null=True, help_text="音频url(>2s)")
    image = CharField(allow_blank=True, allow_null=True, help_text="寸照url")

    class Meta:
        fields = "__all__"


class NewRebotVideoDirectSerializer(serializers.Serializer):
    """直达:hedra视频合成任务"""

    model = IntegerField(allow_null=True, help_text="音频模型ID")
    language = ChoiceField(
        choices=[
            "Chinese",
            "English",
            "Japanese",
            "中英混合",
            "日英混合",
            "多语种混合",
        ],
        help_text='模型语言:["Chinese","English","Japanese","中英混合","日英混合","多语种混合"]',
    )
    chat = CharField(
        allow_blank=True,
        allow_null=True,
        min_length=10,
        # max_length=100,
        help_text="合成文本",
    )
    image = CharField(allow_blank=True, allow_null=True, help_text="寸照url")

    class Meta:
        fields = "__all__"


class AllinpayRobotSyncPostSerializer(serializers.Serializer):
    """lipsync"""

    audio = CharField(max_length=255, help_text="音频url")
    video = CharField(max_length=255, help_text="视频url")

    class Meta:
        fields = "__all__"


class AllinpayRobotSyncDirectSerializer(serializers.Serializer):
    """lipsync"""

    model = IntegerField(allow_null=True, help_text="音频模型ID")
    language = ChoiceField(
        choices=[
            "Chinese",
            "English",
            "Japanese",
            "中英混合",
            "日英混合",
            "多语种混合",
        ],
        help_text='模型语言:["Chinese","English","Japanese","中英混合","日英混合","多语种混合"]',
    )
    chat = CharField(
        allow_blank=True,
        allow_null=True,
        min_length=10,
        # max_length=100,
        help_text="合成文本",
    )
    video = CharField(max_length=255, help_text="视频url")

    class Meta:
        fields = "__all__"


class AllinpayRobotOpencvPostSerializer(serializers.Serializer):
    image = CharField(max_length=255, help_text="图片url")
    audio = CharField(max_length=255, help_text="音频url")

    class Meta:
        fields = "__all__"


class AllinpayRobotOpencvDirectSerializer(serializers.Serializer):
    model = IntegerField(allow_null=True, help_text="音频模型ID")
    language = ChoiceField(
        choices=[
            "Chinese",
            "English",
            "Japanese",
            "中英混合",
            "日英混合",
            "多语种混合",
        ],
        help_text='模型语言:["Chinese","English","Japanese","中英混合","日英混合","多语种混合"]',
    )
    chat = CharField(
        allow_blank=True,
        allow_null=True,
        min_length=10,
        # max_length=100,
        help_text="合成文本",
    )
    image = CharField(max_length=255, help_text="图片url")

    class Meta:
        fields = "__all__"


# ============================================================
class AllinpayRobotListmyShareSerializer(serializers.ModelSerializer):
    """公共好友列表"""

    id = IntegerField(label="ID", read_only=True)
    vid = IntegerField(allow_null=True, help_text="已共享的好友ID")
    isbot = IntegerField(read_only=True, help_text="AI模型ID")
    answer = IntegerField(read_only=True)
    status = IntegerField(read_only=True)
    nicename = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="自己昵称",
    )
    linkforme = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="自定义关系",
    )
    current = DateTimeField(read_only=True)
    lasttime = DateTimeField(read_only=True)
    parent = IntegerField(read_only=True)

    info = SerializerMethodField()
    aaaa = SerializerMethodField()

    class Meta:
        model = AllinpayRobotListmyShare
        fields = "__all__"
        # validators = [UniqueTogetherValidator(queryset=AllinpayRobotListmyShare.objects.all(), fields=('vid', 'answer'))]

    def get_info(self, attr):
        """好友信息"""
        try:
            r = AllinpayRobotList.objects.get(id=attr.vid)
        except BaseException as err:
            return {}
        else:
            return AllinpayRobotListSerializer(r).data

    def get_aaaa(self, attr):
        """创建者信息"""
        try:
            r = AllinpayRobotList.objects.get(isbot=0, parent=attr.answer)
        except BaseException as err:
            return {}
        else:
            return AllinpayRobotListSerializer(r).data

    def validate_vid(self, attr):
        """验证模型状态"""
        try:
            r = AllinpayRobotList.objects.get(id=attr, share=1)
        except BaseException as err:
            raise ValidationError("好友ID错误")
        else:
            return attr


class AllinpayRobotListmySharePostSerializer(serializers.Serializer):
    vid = IntegerField(allow_null=True, help_text="已共享的好友ID")
    pswd = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="验证答案",
    )
    nicename = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="自己昵称",
    )
    linkforme = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="自定义关系",
    )

    class Meta:
        fields = "__all__"

    # def validate_vid(self, attr):
    #     """验证模型状态"""
    #     try:
    #         r = AllinpayRobotList.objects.get(id=attr, isbot__gt=0, share__gt=0)
    #     except BaseException as err:
    #         raise ValidationError("好友ID错误")
    #     else:
    #         return attr


class DepositMoneySerializer(serializers.Serializer):
    """充值修正"""

    bmoney = IntegerField(min_value=0, help_text="代币数量")
    userid = IntegerField(help_text="用户ID")

    class Meta:
        fields = "__all__"

    def validate_userid(self, attr):
        """验证模型状态"""
        try:
            r = AllinpayUserUserList.objects.get(id=attr, status=1)
        except BaseException as err:
            raise ValidationError("用户ID错误")
        else:
            return attr


class AllinpayWxchatSpreadSerializer(serializers.ModelSerializer):
    """创建推广码"""

    id = IntegerField(label="ID", read_only=True)
    answer = IntegerField(allow_null=True, help_text="用户ID")
    # name = ChoiceField(choices=["跨时空畅聊"], allow_blank=True, help_text="小程序名称")
    name = CharField(allow_null=True, allow_blank=True, help_text="小程序ID")
    current = DateTimeField(read_only=True, help_text="创建时间")
    qrcode = CharField(
        read_only=True,
        style={"base_template": "textarea.html"},
        help_text="推广码",
    )

    class Meta:
        model = AllinpayWxchatSpread
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=AllinpayWxchatSpread.objects.all(), fields=("name", "answer")
            )
        ]


class NewUserSpreadSerializer(serializers.Serializer):
    openid = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        help_text="openid",
    )
    answer = IntegerField(help_text="分享者ID")

    class Meta:
        fields = "__all__"


# =======================================================
class TestTasksBaseSerializer(serializers.Serializer):
    event = IntegerField(help_text="模板ID")
    usert = IntegerField(help_text="好友ID")
    answer = IntegerField(help_text="订阅者")
    share = IntegerField(default=0, help_text="是否分享好友0|1")
    video = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        help_text="视频",
    )

    class Meta:
        fields = "__all__"


# print(repr(AllinpayWxchatSpreadSerializer()))
